package reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 获得【运行时】类的信息。
 */
public class Test08 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        /**
         * 1、创建对象
         */
        Class c1 = Class.forName("reflection.User");//通过【Class.forName】创建user对象
        Class c2 = User.class;  //通过【类名.class】创建对象

        /**
         * 2、获得类名
         */
        System.out.println("=============================获得类的名字");
        System.out.println(c1.getName());  //获取类的完整名字（即：包名+类名），结果为：reflection.User
        System.out.println(c1.getSimpleName());  //获取类的简单名字（即：类名），结果为：User
        System.out.println(c2.getName());  //如果我们不知道这个对象在哪个包下，可以用这个思路：用getName()获得完整名字，就知道在哪个包下了

        /**
         * 3、获得类的属性
         */
        System.out.println("=============================获得类的所有public属性");
        Field[] fields = c1.getFields();
        for (Field f1 : fields){
            System.out.println(f1);  //结果为：只获得了User类中的oublic属性
        }

        System.out.println("==============================获得类的所有任意属性");
        Field[] declaredFields = c1.getDeclaredFields();  //注：getDeclaredFields有s
        for (Field f2 : declaredFields){
            System.out.println(f2);  //结果为：获得了User类中的所有属性
        }

        System.out.println("=============================获得类的某个public属性");
        Field wangming = c1.getField("wangming");
        System.out.println(wangming);

        System.out.println("=============================获得类的某个任意属性");
        Field age = c1.getDeclaredField("age");
        System.out.println(age);

        /**
         * 4、获得类的方法
         */
        System.out.println("=============================获得类的所有方法");
        Method[] ms = c1.getMethods();
        for (Method m : ms){
            System.out.println(m);  //获得和本类和父类的所有public方法：equals、toString、hashCode、get&set、notify、notifyAll
        }

        //又是相见恨晚哪！！！先实战用了，才在视频里学到这个。
        System.out.println("=============================获得指定方法");
        //前一个参数是方法名，后一个参数是方法需要传入的参数的类型（没有就填null）。要抛出异常
        Method getName = c1.getMethod("getName", null);
        Method setName = c1.getMethod("setName", String.class);
        System.out.println(getName);
        System.out.println(setName);

        /**
         * 5、获得类的构造器
         */
        System.out.println("=============================获得构造器");
        Constructor[] constructors = c1.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println("获得public的构造器"+constructor);
        }

        Constructor[] declaredConstructors = c1.getDeclaredConstructors();
        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println("获得任意范围的构造器"+declaredConstructor);
        }


    }

}
